﻿using System;
using System.ComponentModel;
using System.Deployment.Application;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using WGM_Client_Net35V2.Properties;

namespace WGM_Client_Net35V2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindowDefault : Window, IMainWindow, INotifyPropertyChanged
    {
        #region Interop Helpers
        [DllImport("user32.dll")]
        private static extern int FlashWindowEx(ref FLASHWINFO pwfi);

        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool SetForegroundWindow(IntPtr hWnd);

        private struct FLASHWINFO
        {
            public Int32 cbSize;
            public IntPtr hwnd;
            public Int32 dwFlags;
            public Int32 uCount;
            public Int32 dwTimeout;
        } 
        #endregion

        public event PropertyChangedEventHandler PropertyChanged;
        private System.Drawing.Image _tempImage = null;
        private bool _pendingImageChange = false;
        private bool _updateCheckInProgress = false;
        public bool IsStartupCompleted { get; private set; }
        private System.Windows.Forms.NotifyIcon _notifyIcon = new System.Windows.Forms.NotifyIcon();
        private int _unreadTabs = 0;
        private bool _invertedImage = false; // used for tray icon blink toggle   
        WGMLocalEngine _wgmEngine;
        DispatcherTimer _retrieveMessagesTimer = new DispatcherTimer();
        DispatcherTimer _retrieveImageTimer = new DispatcherTimer();
        DispatcherTimer _blinkTimer = new DispatcherTimer();
        public System.Windows.Forms.NotifyIcon TrayIcon
        {
            get;
            private set;
        }
        public ContactObject MyContactObject
        {
            get { return _wgmEngine.MyContactObject; }
        }
        public WGMLocalEngine WGMEngine
        {
            get { return _wgmEngine; }
            set
            {
                _wgmEngine = value;
            }
        }
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

         
        
        public MainWindowDefault()
        {
            InitializeComponent();
            _wgmEngine = new WGMLocalEngine(this);
            _mainTabControl.SelectedIndex = 0;           
        
            _retrieveImageTimer.Interval = TimeSpan.FromMinutes(15);
            _retrieveImageTimer.Tick += new EventHandler(_retrieveImageTimer_Tick);

            _retrieveMessagesTimer.Interval = TimeSpan.FromSeconds(Settings.Default.ServerReceiveInterval);
            _retrieveMessagesTimer.Tick += new EventHandler(_retrieveTimer_Tick);

            _blinkTimer.Interval = TimeSpan.FromSeconds(1);
            _blinkTimer.Tick += new EventHandler(_blinkTimer_Tick);

            if (_rememberChk.IsChecked == true)
            {
                _passwordTB.Password = Properties.Settings.Default.LastLoginPassword;
                _usernameTb.Text = Properties.Settings.Default.LastLoginName;
            }
        }

        void CurrentDeployment_CheckForUpdateCompleted(object sender, CheckForUpdateCompletedEventArgs e)
        {
            _updateCheckInProgress = false;
            if (e.Error == null && e.UpdateAvailable)
            {
                _updateRow.Height = new GridLength(15);
            }
            else
            {
                _updateRow.Height = new GridLength(0);
            }
        }
        /// <summary>
        /// Timer handler for blinking the tray icon.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _blinkTimer_Tick(object sender, EventArgs e)
        {
            if (_invertedImage)
            {
                _notifyIcon.Icon = new System.Drawing.Icon(System.Windows.Forms.Application.StartupPath +"\\app_icon_new_message.ico");                
            }
            else
            {
                _notifyIcon.Icon = new System.Drawing.Icon(System.Windows.Forms.Application.StartupPath +"\\app_icon_normal.ico");
            }
            _invertedImage = !_invertedImage;
        }
        /// <summary>
        /// Checks to see if older versions of this software is running.
        /// </summary>
        /// <returns></returns>
        private bool CheckForRunningInstances()
        {
            Process[] processes = Process.GetProcesses();
            foreach (Process process in processes)
            {
                if (HelperFunctions.AreStringsEqual(process.ProcessName, "wgm_client-net35", true))
                    return true;
            }
            return false;
        }        
        /// <summary>
        /// Handler for the timer which retrieves user images.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _retrieveImageTimer_Tick(object sender, EventArgs e)
        {
            _wgmEngine.GetAllUserImages();
            if(_updateCheckInProgress == false)
                CheckForUpdates();
        }
        /// <summary>
        /// Handler for the timer which retrieves messages.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _retrieveTimer_Tick(object sender, EventArgs e)
        {
            _wgmEngine.RetrieveMessages();
        }
        /// <summary>
        /// Handler for the login button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _loginBtn_Click(object sender, RoutedEventArgs e)
        {
            if (!CheckForRunningInstances())
            {
                _loginBtn.IsEnabled = _usernameTb.IsEnabled = _passwordTB.IsEnabled = _createAccountBtn.IsEnabled = false;
                _cancelBtn.IsEnabled = true;
                _loginMessageTb.Text = "Logging in, please wait...";
                _wgmEngine.DoLogin(_usernameTb.Text, _passwordTB.Password, false);
            }
            else
            {
                _loginMessageTb.Text = "An older version of WGM is already running...";
            }
        }
        /// <summary>
        /// Handler for the cancel button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _cancelBtn_Click(object sender, RoutedEventArgs e)
        {
            ShutdownApplication();
        }
        #region TrayIcon
        /// <summary>
        /// Sets up the tray icon with intial settings.
        /// </summary>
        private void SetupTrayIcon()
        {
            _notifyIcon.Icon = new System.Drawing.Icon(System.Windows.Forms.Application.StartupPath +"\\app_icon_normal.ico");
            TrayIcon = _notifyIcon;
            _notifyIcon.Visible = true;

            System.Windows.Forms.MenuItem localOptionsTrayMenu = new System.Windows.Forms.MenuItem("Local Options");
            localOptionsTrayMenu.Click += new EventHandler(localOptionsTrayMenu_Click);
            System.Windows.Forms.MenuItem exitTrayMenu = new System.Windows.Forms.MenuItem("Exit");
            System.Windows.Forms.MenuItem popupTrayMenu = new System.Windows.Forms.MenuItem("Popups");
            System.Windows.Forms.MenuItem popupTrayMenuNewUser = new System.Windows.Forms.MenuItem("Online User Popup");
            System.Windows.Forms.MenuItem popupTrayMenuLeavingUser = new System.Windows.Forms.MenuItem("Leaving User Popup");
            System.Windows.Forms.MenuItem popupTrayMenuNewMessage = new System.Windows.Forms.MenuItem("New Message Popup");

            System.Windows.Forms.MenuItem onlineOptionsTrayMenu = new System.Windows.Forms.MenuItem("Online Options");

            onlineOptionsTrayMenu.Click += new EventHandler(onlineOptionsTrayMenu_Click);
            popupTrayMenuNewUser.Checked = Properties.Settings.Default.PopupContactOnline;
            popupTrayMenuLeavingUser.Checked = Properties.Settings.Default.PopupContactLeaving;
            popupTrayMenuNewMessage.Checked = Properties.Settings.Default.PopupMessages;


            popupTrayMenuNewUser.Click += new EventHandler(popupTrayMenuNewUser_Click);
            popupTrayMenuLeavingUser.Click += new EventHandler(popupTrayMenuLeavingUser_Click);
            popupTrayMenuNewMessage.Click += new EventHandler(popupTrayMenuNewMessage_Click);


            exitTrayMenu.Click += new EventHandler(exitTrayMenu_Click);

            _notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu();

            popupTrayMenu.MenuItems.Add(popupTrayMenuNewUser);
            popupTrayMenu.MenuItems.Add(popupTrayMenuLeavingUser);
            popupTrayMenu.MenuItems.Add(popupTrayMenuNewMessage);


            _notifyIcon.ContextMenu.Popup += new EventHandler(ContextMenu_Popup);

            _notifyIcon.ContextMenu.MenuItems.Add(popupTrayMenu);
            _notifyIcon.ContextMenu.MenuItems.Add(onlineOptionsTrayMenu);
            _notifyIcon.ContextMenu.MenuItems.Add(localOptionsTrayMenu);
            _notifyIcon.ContextMenu.MenuItems.Add("-");
            _notifyIcon.ContextMenu.MenuItems.Add(exitTrayMenu);


            _notifyIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(_notifyIcon_MouseDoubleClick);
            _notifyIcon.Text = "WGM Beta2 - ("+_wgmEngine.MyUsername+")";
        }
        void _notifyIcon_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            this.Show();
            if (_blinkTimer.IsEnabled)
                _blinkTimer.Stop();
            _notifyIcon.Icon = new System.Drawing.Icon(System.Windows.Forms.Application.StartupPath+"\\app_icon_normal.ico");
            SetForegroundWindow(new WindowInteropHelper(this).Handle);
        }

        void ContextMenu_Popup(object sender, EventArgs e)
        {
            _notifyIcon.ContextMenu.MenuItems[0].MenuItems[0].Checked = Properties.Settings.Default.PopupContactOnline;
            _notifyIcon.ContextMenu.MenuItems[0].MenuItems[1].Checked = Properties.Settings.Default.PopupContactLeaving;
            _notifyIcon.ContextMenu.MenuItems[0].MenuItems[2].Checked = Properties.Settings.Default.PopupMessages;
        }

        void exitTrayMenu_Click(object sender, EventArgs e)
        {
            Properties.Settings.Default.Save();
            
            _notifyIcon.Dispose();
            _retrieveImageTimer.Stop();
            _retrieveMessagesTimer.Stop();
            _wgmEngine.DoLogoff();
            this.Close();
            ShutdownApplication();
        }

        void popupTrayMenuNewMessage_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.MenuItem mi = sender as System.Windows.Forms.MenuItem;
            mi.Checked = !mi.Checked;
            Properties.Settings.Default.PopupMessages = mi.Checked;
        }

        void popupTrayMenuLeavingUser_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.MenuItem mi = sender as System.Windows.Forms.MenuItem;
            mi.Checked = !mi.Checked;
            Properties.Settings.Default.PopupContactLeaving = mi.Checked;
        }

        void popupTrayMenuNewUser_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.MenuItem mi = sender as System.Windows.Forms.MenuItem;
            mi.Checked = !mi.Checked;
            Properties.Settings.Default.PopupContactOnline = mi.Checked;
        }

        void onlineOptionsTrayMenu_Click(object sender, EventArgs e)
        {
            OnlineOptionsMenu_Click(sender, null);
            this.Show();
            SetForegroundWindow(new WindowInteropHelper(this).Handle);
            if (this.WindowState == WindowState.Minimized)
            {
                this.WindowState = WindowState.Normal;
            }
        }

        void localOptionsTrayMenu_Click(object sender, EventArgs e)
        {
            LocalOptionsMenu_Click(sender, null);
            this.Show();
            SetForegroundWindow(new WindowInteropHelper(this).Handle);
            if (this.WindowState == WindowState.Minimized)
            {
                this.WindowState = WindowState.Normal;
            }
        }
        #endregion
        #region Interface Methods
        /// <summary>
        /// Called when the wgm engine completes its login process.
        /// </summary>
        /// <param name="result">Value indicating whether the login was successful.</param>
        /// <param name="message">Message associated with this event.</param>
        /// <param name="isReconnect">Value indicating whether this is a reconnect attempt.</param>
        public void LoginCompleted(bool result, string message, bool isReconnect)
        {
            if (result == true)
            {                
                _loginBtn.IsDefault = false;                
                if (Properties.Settings.Default.RememberLogin == true)
                {
                    Properties.Settings.Default.LastLoginName = _usernameTb.Text;
                    Properties.Settings.Default.LastLoginPassword = _passwordTB.Password;
                }
                if (!isReconnect)
                {
                    _loginMessageTb.Text = "Building Contact List...";
                    _wgmEngine.StartExecuting();
                    
                }
            }
            else
            {
                _loginBtn.IsEnabled = _usernameTb.IsEnabled = _passwordTB.IsEnabled = _createAccountBtn.IsEnabled = true;
                _loginMessageTb.Text = message;
            }
        }
        /// <summary>
        /// Callback function for when the wgm engine's startup sequence is completed.
        /// </summary>
        /// <param name="success">Value indicating whether the startup was successful</param>
        public void StartupCompleted(bool success)
        {
            if (!success)
            {
                IsStartupCompleted = false;
                _loginBtn.IsEnabled = _usernameTb.IsEnabled = _passwordTB.IsEnabled = _createAccountBtn.IsEnabled = true;
                _loginTab.IsSelected = true;
                _loginMessageTb.Text = "Connection issues, disconnected...";
                _retrieveImageTimer.Stop();
                _retrieveMessagesTimer.Stop();
            }
            else
            {

                _mainMenu.Visibility = Visibility.Visible;
                _mainTab.IsSelected = true;
                IsStartupCompleted = true;
                _tabs.ItemsSource = _wgmEngine.AllContacts;

                _retrieveMessagesTimer.Start();
                _retrieveImageTimer.Start();
                _wgmEngine.GetAllUserImages();
                CheckForUpdates();
                SetupTrayIcon();
                if(ApplicationDeployment.IsNetworkDeployed)
                    ApplicationDeployment.CurrentDeployment.CheckForUpdateCompleted += new CheckForUpdateCompletedEventHandler(CurrentDeployment_CheckForUpdateCompleted);

                
            }
        }
        /// <summary>
        /// Callback function for when the wgm engine's logoff is completed.
        /// </summary>
        public void LogoffCompleted()
        {
            _loginMessageTb.Text = "Login to WGM";
        }
        /// <summary>
        /// Event handler for when a contact changes it's online status.
        /// </summary>
        /// <param name="co">The changing contact.</param>
        public void ContactChangedOnlineStatus(ContactObject co)
        {
            
            PopupWindow popup = new PopupWindow(this);
            popup.Owner = this;
            
            if (co.ContactIsOnline == true && Settings.Default.PopupContactOnline == true )
            {
                popup.ShowWindow(7, "Contact Online", co.ContactTooltip, co);
            }
            else if(co.ContactIsOnline == false && Settings.Default.PopupContactLeaving == true)
            {
                popup.ShowWindow(7, "Contact Leaving", co.ContactTooltip, co);
            }
        }
        /// <summary>
        /// Interface function to select a contact to be active and show this window.
        /// </summary>
        /// <param name="_destination">Contact to select.</param>
        public void ShowAndSelect(ContactObject _destination)
        {
            this.Show();
            if (_blinkTimer.IsEnabled)
                _blinkTimer.Stop();
            _notifyIcon.Icon = new System.Drawing.Icon(System.Windows.Forms.Application.StartupPath +"\\app_icon_normal.ico");
            SetForegroundWindow(new WindowInteropHelper(this).Handle);
            _destination.IsSelected = true;
            _destination.ClearUnreadMessage();
        }
        public void NetworksRetrievalCompleted(bool success, string statusMessage)
        {
            if (success)
            {
                _networksView.ItemsSource= _wgmEngine.AllNetworks;
                _networksTab.IsSelected = true;

            }
        }
        public void NetWorkJoinCompleted(bool success, string message)
        {

        }
        /// <summary>
        /// Callback function for when a message retrievel is completed by the wgm engine.
        /// </summary>
        /// <param name="messageList">The list of messages retrieved.</param>
        /// <param name="success">Value indicating if the retrieval was successful</param>
        /// <param name="statusMessage">Message associated with this action</param>
        public void MessageRetrievalCompleted(WGM_Client_Net35V2.WGM_Svc.WGMMessage[] messageList, bool success, string statusMessage)
        {
            if (!success)
            {
                if (Settings.Default.AutoReconnect)
                {
                    _wgmEngine.DoLogin(_wgmEngine.MyUsername, _wgmEngine.MyPassword, true);
                    _statusMessageRow.Height = new GridLength(15);
                    _statusMessage.Background = new SolidColorBrush(Colors.OrangeRed);
                }
                else
                {
                    _loginBtn.IsEnabled = _usernameTb.IsEnabled = _passwordTB.IsEnabled = _createAccountBtn.IsEnabled = true;

                    _retrieveMessagesTimer.Stop();
                    _retrieveImageTimer.Stop();
                    _loginTab.IsSelected = true;
                    _loginMessageTb.Text = "Connection issues, disconnected...";
                    IsStartupCompleted = false;
                    if (_notifyIcon != null)
                        _notifyIcon.Dispose();
                }
            }
            else
            {
                _statusMessageRow.Height = new GridLength(0);
            }
        }
        /// <summary>
        /// Callback function for when a text message is received.
        /// </summary>
        /// <param name="destination">The destination contact for this message.</param>
        /// <param name="message">The actual wgm message</param>
        public void ReceiveTextMessage(ContactObject destination,ContactObject sender, WGM_Client_Net35V2.WGM_Svc.WGMMessage message)
        {
            Console.WriteLine(DateTime.Now.ToString() + " ReceiveTextMessage from " + sender.ContactUserName + " to "+destination.ContactUserName + " " +message.MessageType);
            if (destination.IsSelected == false && sender !=null && !sender.ContactIsMe)
            {  
                destination.StartFlashContact();
            }
            if (GetForegroundWindow() != new WindowInteropHelper(this).Handle && Properties.Settings.Default.FlashMainWindowOnNewMessage == true)
                FlashWindow(new WindowInteropHelper(this).Handle);


            if (sender != null && !sender.ContactIsMe)
            {
                if (this.IsVisible == false)
                {
                    if(Settings.Default.PopupMessages)
                        new PopupWindow(this).ShowWindow(10, message, sender, destination);

                    if (!_blinkTimer.IsEnabled)
                        _blinkTimer.Start();
                }
            }
            if (Settings.Default.AutoScrollMessageWindow)
            {
                destination.IncomingViewer.ScrollToBottom();
            }
            
        }
        /// <summary>
        /// Event handler for when a contact's "HasMessages" value changes.
        /// </summary>
        /// <param name="contactObject">The changing contact.</param>
        public void TabHasUnreadChanged(ContactObject contactObject)
        {
            if(contactObject.HasUnreadMessages)
                _unreadTabs++;
            else
                _unreadTabs--;
            CheckUnreadMessages();
        }
        /// <summary>
        /// Event handler for when a contact's selection status changes.
        /// </summary>
        /// <param name="contactObject">The changing contact.</param>
        public void TabSelectionChanged(ContactObject contactObject)
        {
            if (contactObject.IsSelected && contactObject.HasUnreadMessages)
            {
                contactObject.ClearUnreadMessage();
            }
            CheckUnreadMessages();
        }
        /// <summary>
        /// Event handler for when the current user's contact object changes. 
        /// Used to update the UI.
        /// </summary>
        public void MyContactObjectChanged()
        {
            OnPropertyChanged("MyContactObject");
            SetupOnlineOptions();
        }
        /// <summary>
        /// Event handler for when the current user's image changes.
        /// Used to update the UI.
        /// </summary>
        public void MyDisplayImageChanged()
        {
            OnPropertyChanged("MyContactObject");
            OnPropertyChanged("ContactDisplayImage");
        }
        /// <summary>
        /// Interface method to handle errors.
        /// </summary>
        /// <param name="ex"></param>
        public void HandleError(Exception ex)
        {
            
        }
        #endregion
        /// <summary>
        /// Used to flash a window's taskbar holder.
        /// </summary>
        /// <param name="handle">The window handler of the window to flash.</param>
        public void FlashWindow(IntPtr handle)
        {
            //int FLASHW_STOP = 0;
            //int FLASHW_CAPTION = 1;
            //int FLASHW_TRAY = 2;
            int FLASHW_ALL = 3;
            //int FLASHW_TIMER = 4;
            int FLASHW_TIMERNOFG = 12;
            FLASHWINFO pwfi = new FLASHWINFO();
            pwfi.cbSize = Marshal.SizeOf(pwfi);
            pwfi.hwnd = handle;
            pwfi.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG;
            pwfi.uCount = 3;
            pwfi.dwTimeout = 0;
            Int32 intRet = FlashWindowEx(ref pwfi);
        }
        /// <summary>
        /// Checks to see if there are unread messages for a contact.
        /// </summary>
        public void CheckUnreadMessages()
        {
            if (_unreadTabs > 0)
            {
                _unreadMessagesImage.Visibility = Visibility.Visible;
                _unreadMessagesImage.ToolTip = "You have " + _unreadTabs + " tab" + (_unreadTabs > 1 ? "s" : "") + " with unread messages";
                this.Title = "WGM Beta2 - " + _unreadTabs + " tab" + (_unreadTabs > 1 ? "s" : "") + " with unread messages";
                _notifyIcon.Text = "WGM Beta2 - (" + _wgmEngine.MyUsername + ") " + _unreadTabs + " tab" + (_unreadTabs > 1 ? "s" : "") + " with unread messages";
                if (this.IsVisible == false)
                {
                    if(!_blinkTimer.IsEnabled)
                        _blinkTimer.Start();
                }
            }
            else
            {
                _unreadMessagesImage.Visibility = Visibility.Collapsed;
                this.Title = "WGM Beta2";
                _notifyIcon.Text = "WGM Beta2 - (" + _wgmEngine.MyUsername + ")";
            }
        }
        private void CheckForUpdates()
        {
            if (ApplicationDeployment.IsNetworkDeployed)
            {
                _updateCheckInProgress = true;
                ApplicationDeployment.CurrentDeployment.CheckForUpdateAsync();
            }
        }
        /// <summary>
        /// Used to populate the online options window.
        /// </summary>
        private void SetupOnlineOptions()
        {
            Border contactImageBorder = new Border();
            contactImageBorder.CornerRadius = new CornerRadius(5);
            contactImageBorder.Background = new ImageBrush((MyContactObject.ContactDisplayImage.Background as ImageBrush).ImageSource);
            _onlineOptionsDisplayImage.Content = contactImageBorder;
            _onlineOptionsDisplayNameTB.Text = MyContactObject.ContactDisplayName;
            _onlineOptionsDisplayStatusTB.Text = MyContactObject.ContactDisplayStatus;
            _onlineOptionsFontChooser.Text = MyContactObject.ContactUserOptions.UserFontFace;
            _onlineOptionsFontColourR.Value = MyContactObject.ContactUserOptions.FontColourR;
            _onlineOptionsFontColourG.Value = MyContactObject.ContactUserOptions.FontColourG;
            _onlineOptionsFontColourB.Value = MyContactObject.ContactUserOptions.FontColourB;
            _onlineOptionsFontSize.Value = MyContactObject.ContactUserOptions.FontSize;
            _onlineOptionsFontChooser.Foreground = new SolidColorBrush(Color.FromRgb((byte)_onlineOptionsFontColourR.Value,
                                                             (byte)_onlineOptionsFontColourG.Value,
                                                             (byte)_onlineOptionsFontColourB.Value));
            _onlineOptionsFontChooser.FontSize = _onlineOptionsFontSize.Value;
            _onlineOptionsIsBold.IsChecked = MyContactObject.ContactUserOptions.IsFontBold;
            _onlineOptionsIsItalics.IsChecked = MyContactObject.ContactUserOptions.IsFontItalics;
            _onlineOptionsIsUnderlined.IsChecked = MyContactObject.ContactUserOptions.IsFontUnderlined;
            if (MyContactObject.ContactUserOptions.IsFontBold)
                _onlineOptionsFontChooser.FontWeight = FontWeights.Bold;
            if (MyContactObject.ContactUserOptions.IsFontItalics)
                _onlineOptionsFontChooser.FontStyle = FontStyles.Italic;
        }
        /// <summary>
        /// Used to shutdown the current application.
        /// </summary>
        public void ShutdownApplication()
        {
            Process ps = Process.GetCurrentProcess();
            if (_notifyIcon != null)
                _notifyIcon.Dispose();
            ps.Kill();
            ps.Close();
        }
        /// <summary>
        /// Window closing event. Used to minimize the window to the task bar or shut down the application if startup is not yet completed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (IsStartupCompleted)
            {
                this.Hide();

                if (_unreadTabs > 0)
                {
                    if (!_blinkTimer.IsEnabled)
                        _blinkTimer.Start();
                }

                e.Cancel = true;
            }
            else
            {
                ShutdownApplication();
            }
        }
        /// <summary>
        /// Button handler for local options reset.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _resetBtn_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Properties.Settings.Default.Reset();
        }
        /// <summary>
        /// Button handler for local options commit.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _doneBtn_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Properties.Settings.Default.Save();
            _mainTab.IsSelected = true;
        }
        /// <summary>
        /// Menu click handler for local options.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LocalOptionsMenu_Click(object sender, RoutedEventArgs e)
        {
            _localOptionsTab.IsSelected = true;
            
        }
        /// <summary>
        /// Local options slider handler for system colour.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sysColChooser_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            _sFontChooser.Foreground = new SolidColorBrush(Color.FromRgb((byte)Properties.Settings.Default.SystemFontColorR,
                                                             (byte)Properties.Settings.Default.SystemFontColorG,
                                                             (byte)Properties.Settings.Default.SystemFontColorB));
        }
        /// <summary>
        /// Local options slider handler for ovveride colour.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void overColChooser_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            _oFontChooser.Foreground = new SolidColorBrush(Color.FromRgb((byte)Properties.Settings.Default.OverrideIncomingFontColourR,
                                                 (byte)Properties.Settings.Default.OverrideIncomingFontColourG,
                                                 (byte)Properties.Settings.Default.OverrideIncomingFontColourB));

        }
        /// <summary>
        /// Local options slider handler for the window colour.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void winColChooser_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            Properties.Settings.Default.WindowColorScheme = Color.FromRgb((byte)Properties.Settings.Default.WindowColorR,
                                                 (byte)Properties.Settings.Default.WindowColorG,
                                                 (byte)Properties.Settings.Default.WindowColorB);

        }
        /// <summary>
        /// Menu item handler for the about menu.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AboutMenu_Click(object sender, RoutedEventArgs e)
        {
            Border image = new Border();
            image.Background =  new ImageBrush(new BitmapImage(new Uri(System.Windows.Forms.Application.StartupPath+"\\images\\mainicon2.png", UriKind.RelativeOrAbsolute)));
            PopupWindow popup = new PopupWindow(this);
            popup.Owner = this;
            popup.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            if (ApplicationDeployment.IsNetworkDeployed)
            {
                
                
                popup.ShowModal("Wayne's Global Messenger Beta2\r\nVersion " + ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString() + "\r\nWritten by Wayne Hart", "Wayne's Global Messenger", image);
                //MessageBox.Show("Wayne's Global Messenger Beta2\r\nVersion " + ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString() + "\r\nWritten by Wayne Hart", "Wayne's Global Messenger", MessageBoxButton.OK,MessageBoxImage.Information);
            }
            else
            {
                popup.ShowModal("Wayne's Global Messenger Beta2\r\nWritten by Wayne Hart", "Wayne's Global Messenger", image);
            }            
        }
        /// <summary>
        /// Menu item handler for the exit button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ExitMenu_Click(object sender, RoutedEventArgs e)
        {
            exitTrayMenu_Click(sender, null);
        }
        /// <summary>
        /// Context menu handler for right clicking on a contact object with an ongoing conversation.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void clearMessages_Click(object sender, RoutedEventArgs e)
        {
            MenuItem mi = sender as MenuItem;
            string username = mi.Tag as string;
            ContactObject co = _wgmEngine.ListManager.GetContactObject(username,false);
            if (co != null)
            {
                if (co.HasUnreadMessages)
                {
                    PopupWindow popup = new PopupWindow(this);
                    popup.Owner = this;
                    popup.WindowStartupLocation = WindowStartupLocation.CenterOwner;
                    Border contactImageBorder = new Border();
                    contactImageBorder.Background = new ImageBrush((co.ContactDisplayImage.Background as ImageBrush).ImageSource);
  
                    popup.ShowModal("You have unread messages with " + co.ContactDisplayName + "\r\nCheck them before clearing messages", "Wayne's Global Messenger", contactImageBorder);
                    return;
                }
                co.ClearMessages();
            }
        }
        /// <summary>
        /// Online options menu click handler.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnlineOptionsMenu_Click(object sender, RoutedEventArgs e)
        {
            SetupOnlineOptions();
            _onlineOptionsTab.IsSelected = true;
        }

        private void _onlineOptionsCancelBtn_MouseDown(object sender, MouseButtonEventArgs e)
        {
            SetupOnlineOptions();
            _mainTab.IsSelected = true;
        }

        private void _onlineOptionsResetBtn_MouseDown(object sender, MouseButtonEventArgs e)
        {
            SetupOnlineOptions();
        }

        private void _onlineOptionsDoneBtn_MouseDown(object sender, MouseButtonEventArgs e)
        {
            WGM_Svc.UserOptions myNewOptions = new WGM_Client_Net35V2.WGM_Svc.UserOptions();
            myNewOptions.FontColourR =(int) _onlineOptionsFontColourR.Value;
            myNewOptions.FontColourG = (int)_onlineOptionsFontColourG.Value;
            myNewOptions.FontColourB = (int)_onlineOptionsFontColourB.Value;
            myNewOptions.UserName = MyContactObject.ContactUserName;
            myNewOptions.UserStatus = _onlineOptionsDisplayStatusTB.Text;
            myNewOptions.DisplayName = _onlineOptionsDisplayNameTB.Text;
            if (myNewOptions.DisplayName.Trim() == "")
                myNewOptions.DisplayName = myNewOptions.UserName;
            myNewOptions.IsFontBold = _onlineOptionsIsBold.IsChecked == true;
            myNewOptions.IsFontItalics = _onlineOptionsIsItalics.IsChecked == true;
            myNewOptions.IsFontUnderlined = _onlineOptionsIsUnderlined.IsChecked == true;
            myNewOptions.UserFontFace = _onlineOptionsFontChooser.Text;
            myNewOptions.FontSize = (int)_onlineOptionsFontSize.Value;

            _wgmEngine.SetMyUserOptions(myNewOptions);
            if (_pendingImageChange)
            {
                _wgmEngine.SetMyDisplayImage(_tempImage);
            }
            _pendingImageChange = false;
            _mainTab.IsSelected = true;
        }

        private void _onlineOptionsSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            UpdateOnlineOptions();
        }

        private void UpdateOnlineOptions()
        {
            try
            {
                _onlineOptionsFontChooser.Foreground = new SolidColorBrush(Color.FromRgb((byte)_onlineOptionsFontColourR.Value,
                                                     (byte)_onlineOptionsFontColourG.Value,
                                                     (byte)_onlineOptionsFontColourB.Value));
                _onlineOptionsFontChooser.FontSize = _onlineOptionsFontSize.Value;
                if (_onlineOptionsIsBold.IsChecked == true)
                    _onlineOptionsFontChooser.FontWeight = FontWeights.Bold;
                else
                    _onlineOptionsFontChooser.FontWeight = FontWeights.Normal;
                if (_onlineOptionsIsItalics.IsChecked == true)
                    _onlineOptionsFontChooser.FontStyle = FontStyles.Italic;
                else
                    _onlineOptionsFontChooser.FontStyle = FontStyles.Normal;
            }
            catch { }
        }

        private void _onlineOptionsCheckBox_Changed(object sender, RoutedEventArgs e)
        {
            UpdateOnlineOptions();
        }

        private void _onlineOptionsDisplayImage_MouseDown(object sender, MouseButtonEventArgs e)
        {
            System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
            ofd.Filter = "*.bmp|*.bmp|*.png|*.png|*.jpg|*.jpg|*.jpeg|*.jpeg|All Files|*.*";
            ofd.Multiselect = false;
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                FileInfo fi = new FileInfo(ofd.FileName);
                if (fi.Length > (1024 * 500))
                {
                    MessageBox.Show("Please select a file smaller than 500Kb.", "Wayne's Global Messenger", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
                try
                {
                    _tempImage = System.Drawing.Image.FromFile(ofd.FileName);                    
                    Border newImage = new Border();
                    newImage.Background = new ImageBrush(HelperFunctions.GetBitmapFromImage(_tempImage));
                    newImage.CornerRadius = new CornerRadius(5);
                    _onlineOptionsDisplayImage.Content = newImage;
                    _pendingImageChange = true;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Please select a valid image file.\r\n" + ex.ToString(), "Wayne's Global Messenger", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
            }
        }

        private void _onlineOptionsClearImgBtn_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Border blankImage = new Border();
            blankImage.CornerRadius = new CornerRadius(5);
            blankImage.Background = new ImageBrush(new BitmapImage(new Uri(System.Windows.Forms.Application.StartupPath+"\\images\\blank.png", UriKind.RelativeOrAbsolute)));
            _onlineOptionsDisplayImage.Content = blankImage;
            _tempImage = null;
            _pendingImageChange = true;
            
        }
        private void _localOptionsReceiveInterval_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            _retrieveMessagesTimer.Interval = TimeSpan.FromSeconds(_localOptionsReceiveInterval.Value);
        }

        private void _enterNetworkBtn_Click(object sender, RoutedEventArgs e)
        {
            string networkName = (sender as Button).Tag as string;
            _wgmEngine.JoinNetwork(networkName);
            
        }
    }
}
